<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/xiehuan.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/xiehuan.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="虚拟机,JVM," />










<meta name="description" content="关于Java虚拟机的一些记录">
<meta name="keywords" content="虚拟机,JVM">
<meta property="og:type" content="article">
<meta property="og:title" content="JVM第一篇">
<meta property="og:url" content="http://yoursite.com/2019/12/10/JVM第一篇/index.html">
<meta property="og:site_name" content="xiehuan">
<meta property="og:description" content="关于Java虚拟机的一些记录">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://img-blog.csdn.net/20141214124019390?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHRheWZqcGs=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/14105949-52c5b0b0956a4991.png?imageMogr2/auto-orient/strip|imageView2/2/w/870/format/webp">
<meta property="og:image" content="https://ask.qcloudimg.com/http-save/yehe-5522483/zmzre4hkcc.png?imageView2/2/w/1620">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/5982616-aad63782162c9ae5.png?imageMogr2/auto-orient/strip|imageView2/2/w/942/format/webp">
<meta property="og:updated_time" content="2020-01-02T13:50:42.023Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="JVM第一篇">
<meta name="twitter:description" content="关于Java虚拟机的一些记录">
<meta name="twitter:image" content="https://img-blog.csdn.net/20141214124019390?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHRheWZqcGs=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://yoursite.com/2019/12/10/JVM第一篇/"/>





  <title>JVM第一篇 | xiehuan</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">xiehuan</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/12/10/JVM第一篇/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="xiehuan">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="xiehuan">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">JVM第一篇</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2019-12-10T22:03:00+08:00">
                2019-12-10
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Java/" itemprop="url" rel="index">
                    <span itemprop="name">Java</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>关于Java虚拟机的一些记录<br><a id="more"></a></p>
<h2 id="内存结构与内存模型"><a href="#内存结构与内存模型" class="headerlink" title="内存结构与内存模型"></a>内存结构与内存模型</h2><p>什么是内存结构呢？指的是Java虚拟机的方法区，虚拟机栈，本地方法栈，堆，以及程序计数器，也就是Java的内存分布。<br>那么内存模型呢？Java的内存模型是为了屏蔽掉硬件和操作系统的内存访问差异，实现让Java程序在各种平台上面都能达到一致的内存访问效果。</p>
<h3 id="程序计数器"><a href="#程序计数器" class="headerlink" title="程序计数器"></a>程序计数器</h3><p>线程私有的内存。<br>分支，循环，跳转，异常处理，线程恢复等都要依靠程序计数器来完成。<br>如果线程正在执行是的Java方法，计数器中记录的中正在执行的虚拟机字节码指令的地址；<br>如果线程正在执行的是Native方法，计数器为空。<br>程序计数器是虚拟机中唯一一个不会有OutOfMemoryError的内存。</p>
<h3 id="Java虚拟机栈"><a href="#Java虚拟机栈" class="headerlink" title="Java虚拟机栈"></a>Java虚拟机栈</h3><p>线程私有的内存。它描述的是Java方法执行时的内存模型。<br>每个方法在执行是都会创建一个栈帧。栈帧结构如下：<br><img src="https://img-blog.csdn.net/20141214124019390?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHRheWZqcGs=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="栈帧结构"></p>
<ol>
<li>局部变量表<br>用来存放方法参数和方法内部定义的局部变量。在class文件中，方法的Code属性的max_locals数据项中确定了该方法分配的最大容量。以变量槽(Slot)为单位。<br>一个Slot可以存放32位以内的数据类型（6种Java基本数据类型，以及reference（对象引用），returnAddress(指向； 一条字节码指令的地址)）<br>long以及double需要两个Slot。局部变量不像类变量一样存在准备阶段，如果没有赋值，是不能被使用的。</li>
<li>操作数栈<br>操作栈，后入先出。在方法开始执行时，栈为空；在执行过程中，会把字节码指令写入栈中和取出</li>
<li>动态连接<br>class文件中的常量池存在大量符号引用，这些符号引用一部分在类加载阶段或者第一次使用时转化为直接引用，这种转化称为静态解析（方法的重载）；<br>另外一部分在每一次运行时转化为直接引用，这部分称为动态连接（方法的重写）。</li>
<li>方法返回地址<br>正常完成出口与异常完成出口在方法退出之前，都需要返回到方法被调用的位置。<br>正常退出时，调用者的PC计数器的值可以作为返回地址；异常退出时，返回地址需要通过异常处理器表确定。</li>
<li>附加信息</li>
</ol>
<p>局部变量表所需的内存空间在编译期间完成分配。<br>在局部变量表中，当线程请求的栈深度大于虚拟机允许的最大值，将抛出StackOverflowError；<br>虚拟机栈动态扩展无法申请到足够的内存时，会抛出OutOfMemoryError异常。<br>在相同的栈内存空间下，局部变量越少，可以递归调用的次数越多<br>相反，如果有过多的局部变量，则会增加栈内存的开销。</p>
<h3 id="本地方法栈"><a href="#本地方法栈" class="headerlink" title="本地方法栈"></a>本地方法栈</h3><p>本地方法栈为虚拟机使用到的Native方法服务。</p>
<h3 id="Java堆"><a href="#Java堆" class="headerlink" title="Java堆"></a>Java堆</h3><p>堆内存被所有的线程共享。<br>Java堆细分为：新生代，老年代；再细分：Eden空间，From Survivor空间，To Survivor空间。<br>堆中存储的是对象的实例。</p>
<h3 id="方法区-非堆"><a href="#方法区-非堆" class="headerlink" title="方法区(非堆)"></a>方法区(非堆)</h3><p>所有线程共享。<br>存储被虚拟机加载的类信息，常量，静态变量，编译后的代码。因为方法区中存储的是类加载之后的信息，所以我们先来看看<a href="#类加载">类加载是怎么实现的</a></p>
<h4 id="运行时常量"><a href="#运行时常量" class="headerlink" title="运行时常量"></a>运行时常量</h4><p>存放编译期间存在的各种字面量和符号引用（<strong>JAVA并不要求常量只有在编译期间产生，运行期间也可以将新的常量放入池中，譬如String类的intern()方法</strong>）</p>
<h3 id="直接内存"><a href="#直接内存" class="headerlink" title="直接内存"></a>直接内存</h3><p>物理机的直接内存</p>
<h2 id="对象是否死亡"><a href="#对象是否死亡" class="headerlink" title="对象是否死亡"></a>对象是否死亡</h2><h3 id="引用计数算法"><a href="#引用计数算法" class="headerlink" title="引用计数算法"></a>引用计数算法</h3><p>给对象添加一个引用计数器，如果有引用，则+1，如果引用失效，就-1.<br>问题：很难解决对象之间的相互循环引用的问题</p>
<h3 id="可达分析算法"><a href="#可达分析算法" class="headerlink" title="可达分析算法"></a>可达分析算法</h3><h4 id="GCRoot"><a href="#GCRoot" class="headerlink" title="GCRoot"></a>GCRoot</h4><p>虚拟机栈中引用的对象；<br>方法区中类静态属性引用的对象；<br>方法区中常量引用的对象；<br>本地方法栈中Native方法引用的对象</p>
<h2 id="垃圾收集算法"><a href="#垃圾收集算法" class="headerlink" title="垃圾收集算法"></a>垃圾收集算法</h2><h3 id="标记-清除算法"><a href="#标记-清除算法" class="headerlink" title="标记-清除算法"></a>标记-清除算法</h3><p>先标记出所有需要回收的对象，在标记之后统一回收<br>问题：</p>
<ol>
<li>效率—-标记以及清除的过程效率不高</li>
<li>空间—-会产生大量不连续的内存碎片<h3 id="标记-整理算法"><a href="#标记-整理算法" class="headerlink" title="标记-整理算法"></a>标记-整理算法</h3>先标记出所有需要回收的对象，把存活的对象向一端移动，然后清理掉边界以外的内存<h3 id="复制算法"><a href="#复制算法" class="headerlink" title="复制算法"></a>复制算法</h3>将内存分为大小相等的两块，每次只使用其中一块，当使用完之后，就把还存活的对象复制到另外一块内存去，然后再把已经使用过的这块一次性给全部清理掉<br>问题：<br>浪费资源<br>HotSpot将内存划分为一块Eden空间和两块Survivor空间，每次使用Eden空间和其中一块Survivor，当需要回收时，把Eden和Survivor中还存活的对象一次性复制到另外一块Survivor上。<br>内存大小比例—-Eden:Survivor=8:1<br>分配担保机制：如果用来复制的Survivor空间不够时，这些对象会直接进入老年代。<h3 id="分代收集算法"><a href="#分代收集算法" class="headerlink" title="分代收集算法"></a>分代收集算法</h3>根据对象存活周期的不同，将内存划为几块，不同的年代的对象，采用不同的收集算法。</li>
</ol>
<p>GC停顿时需要一致性：在整个可达性分析期间，整个执行系统看起来像是被冻结在某个时间点上，不可以出现分析过程中对象引用还在不断改变的情况，该点不满足的话，分析结果就是不准确的。<br>安全点（safepoint）：在特定的位置才会记录信息，这些位置被称为安全点，安全点的选取基本上是以程序“是否具有让程序长时间执行的特征”<br>长时间执行的特征：指令复用，譬如：方法调用，循环跳转，异常跳转<br>抢先式中断：在发生GC时，主动把线程停止<br>主动式中断：设置一个标志，让各个线程主动去轮询这个标志，当标志为true时，线程自己主动中断挂起。<br>安全区域（safe region）:在一段代码中，引用关系不会发生变化，在安全区域中的任意地方执行GC都是安全的。</p>
<h2 id="垃圾收集器"><a href="#垃圾收集器" class="headerlink" title="垃圾收集器"></a>垃圾收集器</h2><p>虚拟机会对无用的类的进行回收：</p>
<ol>
<li>该类所有的实例都被回收</li>
<li>加载该类的ClassLoader已经被回收</li>
<li>该类对应的class对象没有被任何地方引用，无法通过反射访问该类的方法。<br>HotSpot 虚拟机的垃圾收集器<br><img src="https://upload-images.jianshu.io/upload_images/14105949-52c5b0b0956a4991.png?imageMogr2/auto-orient/strip|imageView2/2/w/870/format/webp" alt="HotSpot 虚拟机的垃圾收集器"><h3 id="serial收集器"><a href="#serial收集器" class="headerlink" title="serial收集器"></a>serial收集器</h3>（复制算法 新生代收集 单线程）<h3 id="Serial-Old收集器"><a href="#Serial-Old收集器" class="headerlink" title="Serial Old收集器"></a>Serial Old收集器</h3>（标记整理算法 老年代收集 单线程）<h3 id="ParNew收集器"><a href="#ParNew收集器" class="headerlink" title="ParNew收集器"></a>ParNew收集器</h3>（标记整理算法 新生代收集 多线程）<h3 id="Parallel-Scavenge收集器"><a href="#Parallel-Scavenge收集器" class="headerlink" title="Parallel Scavenge收集器"></a>Parallel Scavenge收集器</h3>（复制算法 新生代收集 并行多线程）<br>与其他收集器不同的是：Parallel Scavenge收集器目标是达到一个可控制的吞吐量，其他的收集器是为了尽可能的缩短垃圾收集时用户线程的停顿时间<br>吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)<h3 id="Parallel-Old收集器"><a href="#Parallel-Old收集器" class="headerlink" title="Parallel Old收集器"></a>Parallel Old收集器</h3>标记整理算算法 老年代收集 多线程<h3 id="CMS收集器"><a href="#CMS收集器" class="headerlink" title="CMS收集器"></a>CMS收集器</h3>标记清理算法 </li>
<li>初始标记：标记GC Roots能直接关联到的对象（<strong>GC停顿</strong>）</li>
<li>并发标记：进行GC Roots Tracing的过程</li>
<li>重新标记：为了修正并发标记期间因为用户程序继续运作而导致标记产生变化的那一部分对象的标记记录（<strong>GC停顿</strong>）</li>
<li>并发清除：清除</li>
</ol>
<h3 id="G1收集器"><a href="#G1收集器" class="headerlink" title="G1收集器"></a>G1收集器</h3><h2 id="内存分配与回收策略"><a href="#内存分配与回收策略" class="headerlink" title="内存分配与回收策略"></a>内存分配与回收策略</h2><h2 id="类加载"><a href="#类加载" class="headerlink" title="类加载"></a>类加载</h2><p>虚拟机把类的数据从class文件中加载到内存，并且对数据进行校验，转换解析和初始化，最终形成可以被虚拟机使用的Java类型，这就是虚拟机的类加载。</p>
<h3 id="类加载的时机"><a href="#类加载的时机" class="headerlink" title="类加载的时机"></a>类加载的时机</h3><p>类的生命周期<br><img src="https://ask.qcloudimg.com/http-save/yehe-5522483/zmzre4hkcc.png?imageView2/2/w/1620" alt="类的生命周期"><br>加载，验证，准备，初始化，卸载这五步的顺序是确定的，虚拟机没有规定什么时候进行加载动作，但是规定了有且只有5种情况必须立即对类进行“初始化”：</p>
<ol>
<li>遇到new,getstatic,putstatic或者invokestatic字节码指令时，如果类没有初始化，就要先初始化。对应字节码指令的场景：<br>使用new 关键字实例化对象，读取或者设置一个类的静态字段(被final修饰，已经在编译把结果放入常量池的静态字段除外)的时候，调用一个类的静态方法的时候</li>
<li>使用Java.lang.reflect包对类进行反射调用的时候，如果没有初始化，需要初始化；</li>
<li>当初始化一个类的时候，如果发现他的父类还没有进行初始化，则需要先触发父类的初始化。（<strong>这里需要排除掉接口，一个接口在初始化时，并不要求它的父类全部都完成了初始化，只要在真正使用到了付接口的时候，才会去初始化</strong>）</li>
<li>当虚拟机启动的时候，用户需要指定一个执行的主类，虚拟机会先初始化那个类。<br>如果是使用数组的话，是不会先引发那个类的初始化的，由虚拟机先初始化一个虚拟类出来<br>常量在编译阶段会存入调用类的常量池中。<br>常量传播：在编译优化时，将能够计算出结果的变量直接替换为常量。<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">void main()</span><br><span class="line"> &#123;</span><br><span class="line">     int a = 1;</span><br><span class="line">     printf(&quot;%d&quot;,a);</span><br><span class="line"> &#125;</span><br><span class="line"> 编译后</span><br><span class="line"> void main()</span><br><span class="line"> &#123;</span><br><span class="line">      printf(&quot;%d&quot;,1);</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>常量折叠：在编译优化时，多个变量进行计算时，而且能够直接计算出结果，那么变量将由常量直接替换<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">void main()</span><br><span class="line">&#123;</span><br><span class="line">      int a = 3+1-1*5;</span><br><span class="line">      printf(&quot;%d&quot;,a);</span><br><span class="line">&#125;</span><br><span class="line">编译后</span><br><span class="line"></span><br><span class="line">void main()</span><br><span class="line">&#123;</span><br><span class="line">     printf(&quot;%d&quot;,-1);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h3 id="类加载的过程"><a href="#类加载的过程" class="headerlink" title="类加载的过程"></a>类加载的过程</h3><h4 id="加载"><a href="#加载" class="headerlink" title="加载"></a>加载</h4><p>在加载阶段，虚拟机需要完成三件事情：</p>
<ol>
<li>通过一个类的全限定名来获取定义此类的二进制字节流</li>
<li>将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。</li>
<li>在内存中生成一个代表这个类的Class对象，作为方法区这个类的各种数据的访问入口。<br>非数组类的加载是通过类加载器完成的。（<strong>可以使用系统的类加载器，也可以是用户自定义的类加载器</strong>）<br>数组类本身不是通过类加载器创建的，是虚拟机直接创建，但是数组类的元素类型还是需要通过类加载器创建。<h4 id="验证"><a href="#验证" class="headerlink" title="验证"></a>验证</h4>验证class文件的字节流中包含的信息是符合当前虚拟机的要求的。<h4 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h4>为类变量分配内存并且设置类变量初始值，这些变量所使用的内存都将在方法区中进行分配。如果类变量的字段属性表中存在ConstantValue属性，那么该变量在准备阶段就会被指定值<h4 id="解析"><a href="#解析" class="headerlink" title="解析"></a>解析</h4>解析是虚拟机将常量池内的符号引用替换为直接引用的过程</li>
<li>符号引用：以一组符号来描述所引用的目标。符号引用与虚拟机实现的内存布局无关，使用的目标不一定已经加载进内存中。</li>
<li>直接引用：直接引用可以是直接指向目标的指针，相对偏移量或者是一个能间接定位到目标的句柄。直接引用和虚拟机实现的内存布局有关。如果是直接引用，那么引用的目标必定存在在内存中。</li>
<li>类或者接口的解析</li>
<li>类方法的解析</li>
<li>接口方法的解析<h4 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h4>根据程序去初始化类变量的值和其他资源<h3 id="类加载器"><a href="#类加载器" class="headerlink" title="类加载器"></a>类加载器</h3>实现通过类的全限定名获取此类的二进制字节流的模块叫做类加载器<br>双亲委派模型<br><img src="https://upload-images.jianshu.io/upload_images/5982616-aad63782162c9ae5.png?imageMogr2/auto-orient/strip|imageView2/2/w/942/format/webp" alt="双亲委派模型"><br>启动类加载器：&lt;JAVA_HOME&gt;\lib目录下，或者被-Xbootclasspath参数指定的路径的类库加载到虚拟机内存中<br>扩展类加载器：&lt;JAVA_HOME&gt;\lib\ext目录下，或者被Java-ext-dirs系统变量执行路径的类库<br>引用程序类加载器：有sun.misc.Launcher$AppClassLoader实现<br>工作原理：如果一个类加载器收到了类加载请求，它并不会自己先去加载，而是把这个请求委托给父类的加载器去执行，如果父类加载器还存在其父类加载器，则进一步向上委托，依次递归，请求最终将到达顶层的启动类加载器，如果父类加载器可以完成类加载任务，就成功返回，倘若父类加载器无法完成此加载任务，子加载器才会尝试自己去加载，这就是双亲委派模式</li>
</ol>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/虚拟机/" rel="tag"># 虚拟机</a>
          
            <a href="/tags/JVM/" rel="tag"># JVM</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2019/11/22/IDEA快捷键/" rel="next" title="IDEA快捷键">
                <i class="fa fa-chevron-left"></i> IDEA快捷键
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2020/07/02/SpringBoot启动/" rel="prev" title="'SpringBoot启动'">
                'SpringBoot启动' <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">xiehuan</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/">
              
                  <span class="site-state-item-count">28</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                
                  <span class="site-state-item-count">7</span>
                  <span class="site-state-item-name">分类</span>
                
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                
                  <span class="site-state-item-count">27</span>
                  <span class="site-state-item-name">标签</span>
                
              </div>
            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#内存结构与内存模型"><span class="nav-number">1.</span> <span class="nav-text">内存结构与内存模型</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#程序计数器"><span class="nav-number">1.1.</span> <span class="nav-text">程序计数器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Java虚拟机栈"><span class="nav-number">1.2.</span> <span class="nav-text">Java虚拟机栈</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#本地方法栈"><span class="nav-number">1.3.</span> <span class="nav-text">本地方法栈</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Java堆"><span class="nav-number">1.4.</span> <span class="nav-text">Java堆</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#方法区-非堆"><span class="nav-number">1.5.</span> <span class="nav-text">方法区(非堆)</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#运行时常量"><span class="nav-number">1.5.1.</span> <span class="nav-text">运行时常量</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#直接内存"><span class="nav-number">1.6.</span> <span class="nav-text">直接内存</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#对象是否死亡"><span class="nav-number">2.</span> <span class="nav-text">对象是否死亡</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#引用计数算法"><span class="nav-number">2.1.</span> <span class="nav-text">引用计数算法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#可达分析算法"><span class="nav-number">2.2.</span> <span class="nav-text">可达分析算法</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#GCRoot"><span class="nav-number">2.2.1.</span> <span class="nav-text">GCRoot</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#垃圾收集算法"><span class="nav-number">3.</span> <span class="nav-text">垃圾收集算法</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#标记-清除算法"><span class="nav-number">3.1.</span> <span class="nav-text">标记-清除算法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#标记-整理算法"><span class="nav-number">3.2.</span> <span class="nav-text">标记-整理算法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#复制算法"><span class="nav-number">3.3.</span> <span class="nav-text">复制算法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#分代收集算法"><span class="nav-number">3.4.</span> <span class="nav-text">分代收集算法</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#垃圾收集器"><span class="nav-number">4.</span> <span class="nav-text">垃圾收集器</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#serial收集器"><span class="nav-number">4.1.</span> <span class="nav-text">serial收集器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Serial-Old收集器"><span class="nav-number">4.2.</span> <span class="nav-text">Serial Old收集器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#ParNew收集器"><span class="nav-number">4.3.</span> <span class="nav-text">ParNew收集器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Parallel-Scavenge收集器"><span class="nav-number">4.4.</span> <span class="nav-text">Parallel Scavenge收集器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Parallel-Old收集器"><span class="nav-number">4.5.</span> <span class="nav-text">Parallel Old收集器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#CMS收集器"><span class="nav-number">4.6.</span> <span class="nav-text">CMS收集器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#G1收集器"><span class="nav-number">4.7.</span> <span class="nav-text">G1收集器</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#内存分配与回收策略"><span class="nav-number">5.</span> <span class="nav-text">内存分配与回收策略</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#类加载"><span class="nav-number">6.</span> <span class="nav-text">类加载</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#类加载的时机"><span class="nav-number">6.1.</span> <span class="nav-text">类加载的时机</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#类加载的过程"><span class="nav-number">6.2.</span> <span class="nav-text">类加载的过程</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#加载"><span class="nav-number">6.2.1.</span> <span class="nav-text">加载</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#验证"><span class="nav-number">6.2.2.</span> <span class="nav-text">验证</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#准备"><span class="nav-number">6.2.3.</span> <span class="nav-text">准备</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#解析"><span class="nav-number">6.2.4.</span> <span class="nav-text">解析</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#初始化"><span class="nav-number">6.2.5.</span> <span class="nav-text">初始化</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#类加载器"><span class="nav-number">6.3.</span> <span class="nav-text">类加载器</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">xiehuan</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Gemini</a> v5.1.4</div>




        







       <p>Hosted by <a href="https://pages.coding.me" style="font-weight: bold">Coding Pages</a></p>
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
